#!/bin/sh /etc/rc.common
# Copyright (C) 2014 Emong
# http://blog.emong.me

START=99
PREFIX=/tmp/etc/kxsw
init() {
	. /lib/functions.sh
	. /lib/functions/network.sh
	config_load kxsw
}

del_fakedns_rule() {
	iptables -t mangle -F GDNS
	iptables -t mangle -D PREROUTING -p udp --sport 53 -j GDNS
	iptables -t mangle -X GDNS
}

add_fakedns_rule() {
	iptables -t mangle -N GDNS
	iptables -t mangle -I PREROUTING -p udp --sport 53 -j GDNS
	cat /etc/kxsw/fakedns |awk -F . '{printf("iptables -t mangle -A GDNS -m string --algo bm --hex-string \"|%02x %02x %02x %02x|\" --from 60 --to 180 -j DROP\n",$1,$2,$3,$4)}' |sh
}

del_ipset() {
	local setname=$1
	ipset -X $setname
}

add_ipset() {
	local setname=$1
	local filename=$2
	[ -z "$filename" ] && filename=$1
	ipset -N $setname nethash --hashsize 40000 --probes 2
	cat /etc/kxsw/$filename |awk '{if($0)print "-A '$setname' "$0}' >$PREFIX/${setname}-ipset
	ipset -R <$PREFIX/${setname}-ipset
	rm $PREFIX/${setname}-ipset
}

append_ss_config() {
	name=$3
	[ -z "$name" ] && name=test
	echo "    \"$1\":\"$2\","  >>$PREFIX/ss-$name
}

ss_get() {
	config_get server $1 server
	config_get enable $1 enable
	config_get startlocal $1 startlocal
	config_get startredir $1 startredir
	config_get ipsetreverse $1 ipsetreverse
	config_get server_port $1 server_port
	config_get local_port $1 local_port
	config_get redir_port $1 redir_port
	config_get dports $1 dports
	config_get password $1 password
	config_get method $1 method
	config_get timeout $1 timeout
	[ "$enable" == "1" ] && {
		echo "{" >$PREFIX/ss-$1
		append_ss_config server $server $1
		append_ss_config server_port $server_port $1
		append_ss_config local_port $local_port $1
		append_ss_config password $password $1
		append_ss_config method $method $1
		append_ss_config timeout $timeout $1
		echo "}" >>$PREFIX/ss-$1
		[ "$startlocal" == "1" ] && ss-local -c $PREFIX/ss-$1 -f /var/run/ss-local-$1.pid
		[ "$startredir" == "1" ] && ss-redir -c $PREFIX/ss-$1 -l $redir_port -f /var/run/ss-redir-$1.pid
		add_ipset $1
		local cmd_str
		[ -n "$dports" ] && cmd_str="-m multiport --dports $dports"
		if [ "$ipsetreverse" == "1" ]
		then
			cmd_str=${cmd_str}" -m set ! --match-set $1 dst"
			add_ipset $1 SPECIAL
		else
			cmd_str=${cmd_str}" -m set --match-set $1 dst"
		fi
		[ "$startredir" == "1" ] && iptables -t nat -A kxsw -p tcp $cmd_str -j REDIRECT --to-ports $redir_port
	}
}

redsocks_get() {
	config_get enable $1 enable
	config_get local_port $1 local_port
	config_get proxy_ip $1 proxy_ip
	config_get proxy_port $1 proxy_port
	config_get proxy_type $1 proxy_type
	config_get autoproxy $1 autoproxy
	config_get timeout $1 timeout
	config_get ipsetreverse $1 ipsetreverse
	config_get dports $1 dports
	[ "$enable" == "1" ] && {
		sed -e "s#|local_port|#$local_port#g" \
		    -e "s#|proxy_ip|#$proxy_ip#g" \
		    -e "s#|proxy_port|#$proxy_port#g" \
		    -e "s#|proxy_type|#$proxy_type#g" \
		    -e "s#|autoproxy|#$autoproxy#g" \
		    -e "s#|timeout|#$timeout#g" \
		    /etc/kxsw/redsocks.conf.template >$PREFIX/redsocks-$1.conf
		redsocks2 -c $PREFIX/redsocks-$1.conf
		add_ipset $1
		local ipset_flag multiports
		[ "$ipsetreverse" == "1" ] && {
			ipset_flag="!"
			add_ipset $1 SPECIAL
		}
		[ -n "$dports" ] && multiports="-m multiport --dports $dports"
		iptables -t nat -A kxsw -p tcp $multiports -m set $ipset_flag --match-set $1 dst -j REDIRECT --to-ports $local_port
	}
}

start() {
	init
	stop
	config_get fakedns_enable fakedns enable
	mkdir -p $PREFIX
	iptables -t nat -N kxsw
	iptables -t nat -A PREROUTING -p tcp -j kxsw
	[ "$fakedns_enable" == "1" ] && add_fakedns_rule
	config_foreach ss_get shadowsocks
	config_foreach redsocks_get redsocks2
	
}

stop() {
	init
	killall ss-local ss-redir
	killall redsocks2
	sleep 1
	killall -9 ss-local ss-redir redsocks2
	iptables -t nat -F kxsw
	iptables -t nat -D PREROUTING -p tcp -j kxsw
	iptables -t nat -X kxsw	
	del_fakedns_rule
	config_foreach del_ipset shadowsocks
	config_foreach del_ipset redsocks2
	rm -fr $PREFIX
}

